package structure.stack;

/**
 * @Author wangj
 * @Date 2022/4/22 21:40
 * 使用栈实现计算器，中缀表达式实现计算器
 * 1，创建两个栈，一个数栈，一个符号栈
 * 2，对表达式进行遍历，如果是数字直接入数栈(注意，这里对多位数的处理)
 * 3，如果是操作符，则需要比较操作符的优先级：
 * 3.1，如果符号栈为空，则直接入符号栈
 * 3.2，如果当前操作符的优先级高于操作符栈中的符号优先级，则操作符直接入栈
 * 3.3，如果当前操作符的优先级小于操作符栈中的符号优先级，则从符号栈中弹出符号，并从数栈中弹出两个数，进行运算之后将结果
 * 入数栈，并将操作符入符号栈
 * 4，最后依次弹出数栈和符号栈进行计算，并将结果保存到数栈
 * 5，数栈中最后的数值就是表达式结果
 */
public class CalculatorByStackMain {

    public static void main(String[] args) {
        CalculatorStack numStack = new CalculatorStack(10);
        CalculatorStack operationStack = new CalculatorStack(10);
        String expression = "9+5*3-4";
        int preNum = 0, afterNum = 0, operation = 0;
        //遍历表达式的索引
        int index = 0;
        //针对多位数拼接的字符串
        String keepNum = "";
        String num = "";

        while (index <= expression.length() - 1) {
            num = expression.substring(index, index + 1);
            if (!numStack.isOperation(num.charAt(0))) {
                // 如果当前不是操作符
                if (index == expression.length() - 1) {
                    numStack.push(Integer.parseInt(num));
                } else {
                    keepNum += num;
                    if (numStack.isOperation(expression.substring(index + 1, index + 2).charAt(0))) {
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
            } else {
                // 判断当前是操作符，先判断操作符栈是否为空
                if(operationStack.isEmpty()){
                    operationStack.push(num.charAt(0));
                }else {
                    // 如果当前符号操作符的优先级高于栈中符号优先级，则直接计算
                    if(operationStack.priority(num.charAt(0)) > operationStack.priority(operationStack.peek())){
                        operationStack.push(num.charAt(0));
                    }else{
                        operation = operationStack.pop();
                        preNum = numStack.pop();
                        afterNum = numStack.pop();
                        int result = numStack.calculator(preNum, afterNum, (char) operation);
                        numStack.push(result);
                        operationStack.push(num.charAt(0));
                    }
                }
            }
            index++;
        }

        // 当上述完成之后，需要依次对栈中数据进行操作
        while (!operationStack.isEmpty()){
            operation = operationStack.pop();
            preNum = numStack.pop();
            afterNum = numStack.pop();
            int result = numStack.calculator(preNum, afterNum, (char) operation);
            numStack.push(result);
        }
        System.out.println(numStack.pop());
    }
}